package com.agileboot.domain.airport.inspectionCheck;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.agileboot.common.core.page.PageDTO;
import com.agileboot.domain.airport.inspection.SirInspectionApplicationService;
import com.agileboot.domain.airport.inspection.command.UpdateSirInspectionCommand;
import com.agileboot.domain.airport.inspection.dto.SirInspectionDTO;
import com.agileboot.domain.airport.reform.ReformMainApplicationService;
import com.agileboot.domain.airport.reform.command.AddReformMainCommand;
import com.agileboot.domain.airport.reform.db.SirReformMainEntity;
import com.agileboot.domain.airport.reform.db.SirReformMainServiceImpl;
import com.agileboot.domain.airport.report.ReportApplicationService;
import com.agileboot.domain.airport.report.command.AddReportCommand;
import com.agileboot.domain.airport.report.db.SirReportEntity;
import com.agileboot.domain.airport.report.db.SirReportServiceImpl;
import com.agileboot.domain.airport.selfcheck.dto.SirSelfCheckDTO;
import com.agileboot.domain.common.command.BulkOperationCommand;
import com.agileboot.domain.airport.inspection.db.SirInspectionEntity;
import com.agileboot.domain.airport.inspection.db.SirInspectionService;
import com.agileboot.domain.airport.inspectionCheck.command.AddInspectionCheckCommand;
import com.agileboot.domain.airport.inspectionCheck.command.UpdateInspectionCheckCommand;
import com.agileboot.domain.airport.inspectionCheck.db.SirInspectionCheckEntity;
import com.agileboot.domain.airport.inspectionCheck.db.SirInspectionCheckService;
import com.agileboot.domain.airport.inspectionCheck.dto.InspectionCheckDTO;
import com.agileboot.domain.airport.inspectionCheck.model.InspectionCheckModel;
import com.agileboot.domain.airport.inspectionCheck.model.InspectionCheckModelFactory;
import com.agileboot.domain.airport.inspectionCheck.query.InspectionCheckQuery;
import com.agileboot.domain.airport.standard.db.SirCheckStandardEntity;
import com.agileboot.domain.airport.standard.db.SirCheckStandardService;
import com.agileboot.domain.airport.selfcheck.db.SirSelfCheckEntity;
import com.agileboot.domain.airport.selfcheck.db.SirSelfCheckServiceImpl;
import com.agileboot.domain.airport.checkTerm.db.SirCheckTermEntity;
import com.agileboot.domain.airport.checkTerm.db.SirCheckTermServiceImpl;
import com.agileboot.domain.system.dept.DeptApplicationService;
import com.agileboot.domain.system.dept.db.SysDeptEntity;
import com.agileboot.domain.system.dept.db.SysDeptService;
import com.agileboot.domain.system.user.UserApplicationService;
import com.agileboot.domain.system.user.db.SearchUserDO;
import com.agileboot.domain.system.user.db.SysUserEntity;
import com.agileboot.domain.system.user.db.SysUserService;
import com.agileboot.domain.system.user.dto.UserDTO;
import com.agileboot.domain.system.user.dto.UserDetailDTO;
import com.agileboot.domain.system.user.query.SearchUserQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.jdbc.core.JdbcTemplate;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class InspectionCheckApplicationService {

    private final InspectionCheckModelFactory modelFactory;

    @Qualifier("sirInspectionCheckServiceImpl")
    private final SirInspectionCheckService inspectionCheckService;

    private final SirInspectionService sirInspectionService;
    private final SysUserService sysUserService;
    private final DeptApplicationService deptApplicationService;
    private final SirCheckStandardService sirCheckStandardService;
    private final SirSelfCheckServiceImpl sirSelfCheckService;
    private final SirCheckTermServiceImpl sirCheckTermService;
    private final UserApplicationService userApplicationService; // 新增注入
    private final ReformMainApplicationService reformMainApplicationService; // 新增注入
    private final ReportApplicationService reportApplicationService; // 新增注入
    private final SirReformMainServiceImpl sirReformMainService;
    private final SirReportServiceImpl sirReportService;
    private final SirInspectionApplicationService sirInspectionApplicationService;
    private final JdbcTemplate jdbcTemplate; // 注入 JdbcTemplate
    private final SysDeptService sysDeptService;

    /**
     * 定时任务，每半小时执行一次，删除 inspection_id 不在 sir_inspection 表中的 sir_inspection_check 记录
     */
    @Scheduled(cron = "0 0/30 * * * ?")
    public void cleanInvalidInspectionCheckRecords() {
        String sql = "DELETE FROM sir_inspection_check WHERE inspection_id NOT IN (SELECT inspection_id FROM sir_inspection)";
        jdbcTemplate.update(sql);
    }


    public PageDTO<InspectionCheckDTO> getInspectionCheckList(InspectionCheckQuery query) {
        // 添加根据inspectionUserName查询用户并设置creator_id的逻辑
        if (StrUtil.isNotEmpty(query.getInspectionUserName())) {
            SearchUserQuery<SearchUserDO> userQuery = new SearchUserQuery<>();
            userQuery.setUsername(query.getInspectionUserName());

            // 调用UserApplicationService的getUserList方法查询用户
            PageDTO<UserDTO> userPage = userApplicationService.getUserList(userQuery);
            // 非空校验
            if (userPage != null && CollUtil.isNotEmpty(userPage.getRows())) {
                UserDTO userDTO = userPage.getRows().get(0);
                if (userDTO != null && userDTO.getUserId() != null) {
                    query.setInspectionUserId(userDTO.getUserId());
                }
            }else {
                query.setInspectionUserId(9999999L);

            }
        }

        Page<SirInspectionCheckEntity> page = inspectionCheckService.page(query.toPage(), query.toQueryWrapper());
        List<InspectionCheckDTO> records = convertToDTOs(page.getRecords());
        return new PageDTO<>(records, page.getTotal());
    }

    public List<InspectionCheckDTO> getInspectionCheckListAll(InspectionCheckQuery query) {
        List<SirInspectionCheckEntity> list = inspectionCheckService.list(query.toQueryWrapper());
        return convertToDTOs(list);
    }

    public InspectionCheckDTO getInspectionCheckInfo(Long id) {
        SirInspectionCheckEntity byId = inspectionCheckService.getById(id);
        return convertToDTOs(Collections.singletonList(byId)).get(0);
    }


    private List<InspectionCheckDTO> convertToDTOs(List<SirInspectionCheckEntity> entities) {
        if (entities.isEmpty()) {
            return Collections.emptyList();
        }

        // 收集所有需要查询的 ID
        Set<Long> selfcheckIds = new HashSet<>();
        Set<Long> checkStandardIds = new HashSet<>();
        Set<Long> checkTermIds = new HashSet<>();
        // 新增：收集 inspectionUserId 和 inspectionId
        Set<Long> inspectionUserIds = new HashSet<>();
        Set<Long> inspectionIds = new HashSet<>();
        Set<Long> deptIds = new HashSet<>();

        Set<Long> inspectionCheckIds = new HashSet<>();


        for (SirInspectionCheckEntity entity : entities) {
            selfcheckIds.add(entity.getSelfcheckId());
            inspectionCheckIds.add(entity.getInspectionCheckId());  // 收集inspectionCheckId

            if (entity.getCheckStandardId() != null) {
                checkStandardIds.add(entity.getCheckStandardId());
            }
            if (entity.getCheckTermId() != null) {
                checkTermIds.add(entity.getCheckTermId());
            }
            // 新增：添加 inspectionUserId 和 inspectionId
            if (entity.getInspectionUserId() != null) {
                inspectionUserIds.add(entity.getInspectionUserId());
            }
            if (entity.getInspectionId() != null) {
                inspectionIds.add(entity.getInspectionId());
            }
            if (entity.getDutyDeptId() != null) {
                deptIds.add(entity.getDutyDeptId());
            }
            if (entity.getCurDealDeptId() != null) {
                deptIds.add(entity.getCurDealDeptId());
            }
        }

        Map<Long, SirSelfCheckEntity> selfCheckMap = new HashMap<>();
        Map<Long, SirCheckStandardEntity> checkStandardMap = new HashMap<>();
        Map<Long, SirCheckTermEntity> checkTermMap = new HashMap<>();
        Map<Long, SysDeptEntity> deptMap = new HashMap<>();
        Map<Long, SysUserEntity> userMap = new HashMap<>();
        Map<Long, SirInspectionEntity> inspectionMap = new HashMap<>();
        // 新增：报告和整改信息映射
        Map<Long, SirReportEntity> reportMap = new HashMap<>();
        Map<Long, SirReformMainEntity> reformMap = new HashMap<>();


        // 批量查询自查库
        if (!selfcheckIds.isEmpty()) {
            selfCheckMap = sirSelfCheckService.getByIds(new ArrayList<>(selfcheckIds)).stream()
                    .collect(Collectors.toMap(SirSelfCheckEntity::getId, e -> e));
        }
        if (!checkStandardIds.isEmpty()) {
            checkStandardMap = sirCheckStandardService.getByCheckStandardIds(new ArrayList<>(checkStandardIds)).stream()
                    .collect(Collectors.toMap(SirCheckStandardEntity::getCheckStandardId, e -> e));
            // 从 SirCheckStandardEntity 中收集 checkTermId
            for (SirCheckStandardEntity standard : checkStandardMap.values()) {
                if (standard.getCheckTermId() != null) {
                    checkTermIds.add(standard.getCheckTermId());
                }
            }
        }
        if (!checkTermIds.isEmpty()) {
            checkTermMap = sirCheckTermService.getByCheckTermIds(new ArrayList<>(checkTermIds)).stream()
                    .collect(Collectors.toMap(SirCheckTermEntity::getCheckTermId, e -> e));
        }

        // 新增：批量查询用户信息
        if (!inspectionUserIds.isEmpty()) {
            userMap = sysUserService.getByUserIds(new ArrayList<>(inspectionUserIds)).stream()
                    .collect(Collectors.toMap(SysUserEntity::getUserId, e -> e));
        }

        // 新增：批量查询检查计划信息
        if (!inspectionIds.isEmpty()) {
            inspectionMap = sirInspectionService.getByIds(new ArrayList<>(inspectionIds)).stream()
                    .collect(Collectors.toMap(SirInspectionEntity::getInspectionId, e -> e));

            // 新增：从检查计划中收集部门ID用于查询
            for (SirInspectionEntity inspection : inspectionMap.values()) {
                if (inspection.getInspectionDeptId() != null) {
                    deptIds.add(inspection.getInspectionDeptId());
                }
                if (inspection.getDeptId() != null) {
                    deptIds.add(inspection.getDeptId());
                }
            }
        }

        if (!deptIds.isEmpty()) {
            deptMap = sysDeptService.getByDeptIds(new ArrayList<>(deptIds)).stream()
                    .collect(Collectors.toMap(com.agileboot.domain.system.dept.db.SysDeptEntity::getDeptId, e -> e));
        }

        // 新增：批量查询报告信息
        if (!inspectionCheckIds.isEmpty()) {
            List<SirReportEntity> reportEntities = sirReportService.getByInspectionCheckIdList(new ArrayList<>(inspectionCheckIds));
            reportMap = reportEntities.stream()
                    .collect(Collectors.toMap(SirReportEntity::getInspectionCheckId, e -> e, (k1, k2) -> k1));
        }

        // 新增：批量查询整改信息
        if (!inspectionCheckIds.isEmpty()) {
            List<SirReformMainEntity> reformEntities = sirReformMainService.getByRelatedQuestionIds(new ArrayList<>(inspectionCheckIds));
            reformMap = reformEntities.stream()
                    .collect(Collectors.toMap(SirReformMainEntity::getRelatedQuestionId, e -> e, (k1, k2) -> k1));
        }


        // 转换为 DTO 并赋值
        List<InspectionCheckDTO> dtos = new ArrayList<>();
        for (SirInspectionCheckEntity entity : entities) {
            InspectionCheckDTO dto = new InspectionCheckDTO(entity);
            // 设置责任部门名称
            if (entity.getDutyDeptId() != null) {
                SysDeptEntity dept = deptMap.get(entity.getDutyDeptId());
                if (dept != null) {
                    dto.setDutyDeptName(dept.getDeptName());
                }
            }

            // 设置处理单位名称
            if (entity.getCurDealDeptId() != null) {
                SysDeptEntity dept = deptMap.get(entity.getCurDealDeptId());
                if (dept != null) {
                    dto.setCurDealDeptName(dept.getDeptName());
                }
            }

            if (checkTermMap.get(entity.getCheckTermId()) != null) {
                SirCheckTermEntity checkTerm = checkTermMap.get(entity.getCheckTermId());
                dto.setProfessional(checkTerm.getProfessionName());
                dto.setCheckContent(checkTerm.getCheckTermContent());
                dto.setCheckStandardCode(checkTerm.getCheckTermCode());
                dto.setCheckStandard(checkTerm.getCheckTermStandard());
            }

            if (entity.getCheckStandardId() != null) {
                SirCheckStandardEntity standard = checkStandardMap.get(entity.getCheckStandardId());
                dto.setDeterminationStandard(standard != null ? standard.getDeterminationStandard() : null);

                if (standard != null) {
                    dto.setComplianceCriteria(standard.getDeterminationStandard());
                    dto.setCheckMethod("远程文件，实地文件");
                    dto.setCompanyBasis(standard.getAccordanceName());
                    dto.setCompanyClause(standard.getAccordanceName());

                    // 通过 checkStandard 的 checkTermId 找到对应的 checkTerm 并设置
                    if (standard.getCheckTermId() != null) {
                        SirCheckTermEntity checkTerm = checkTermMap.get(standard.getCheckTermId());
                        if (checkTerm != null) {
                            dto.setProfessional(checkTerm.getProfessionName());
                            dto.setCheckContent(checkTerm.getCheckTermContent());
                            dto.setCheckStandardCode(checkTerm.getCheckTermCode());
                            dto.setCheckStandard(checkTerm.getCheckTermStandard());
                        }
                    }
                }
            }

            if (selfCheckMap.get(entity.getSelfcheckId())!=null) {
                SirSelfCheckEntity selfCheck = selfCheckMap.get(entity.getSelfcheckId());
                if (selfCheck != null) {
                    dto.setDeterminationStandard(selfCheck.getCheckStandard());
                    dto.setProfessional(selfCheck.getProfessional());
                    dto.setCheckContent(selfCheck.getCheckContent());
                    dto.setCheckStandardCode(selfCheck.getCheckStandardCode());
                    dto.setCheckStandard(selfCheck.getCheckStandard());
                    dto.setComplianceCriteria(selfCheck.getComplianceCriteria());
                    dto.setCheckMethod(selfCheck.getCheckMethod());
                    dto.setCompanyBasis(selfCheck.getCompanyBasis());
                    dto.setCompanyClause(selfCheck.getCompanyClause());
                    dto.setLawsBasis(selfCheck.getLawsBasis());
                    dto.setLawsClause(selfCheck.getLawsClause());
                    dto.setBaseCycle(selfCheck.getBaseCycle());
                    dto.setIntegrationSource(selfCheck.getIntegrationSource());
                    dto.setCheckDepartments(selfCheck.getCheckDepartments());
                }
            }

            // 新增：设置用户名称
            if (entity.getInspectionUserId() != null) {
                SysUserEntity user = userMap.get(entity.getInspectionUserId());
                if (user != null) {
                    dto.setInspectionUserName(user.getUsername());
                }
            }

            if (entity.getInspectionId() != null) {
                SirInspectionEntity inspection = inspectionMap.get(entity.getInspectionId());
                if (inspection != null) {
                    dto.setInspectionName(inspection.getInspectionName());

                    // 修改：直接使用entity的dutyDeptId和curDealDeptId设置检查部门和被检查部门名称
                    if (entity.getDutyDeptId() != null) {
                        SysDeptEntity checkDept = deptMap.get(entity.getDutyDeptId());
                        if (checkDept != null) {
                            dto.setCheckDeptName(checkDept.getDeptName());
                        }
                    }

                    if (entity.getCurDealDeptId() != null) {
                        SysDeptEntity inspectedDept = deptMap.get(entity.getCurDealDeptId());
                        if (inspectedDept != null) {
                            dto.setInspectedDeptName(inspectedDept.getDeptName());
                        }
                    }
                }
            }

            // 新增：设置报告ID和整改编号
            Long checkId = entity.getInspectionCheckId();
            SirReportEntity report = reportMap.get(checkId);
            if (report != null) {
                dto.setReportId(String.valueOf(report.getReportId()));
            }

            SirReformMainEntity reform = reformMap.get(checkId);
            if (reform != null) {
                dto.setReformCode(reform.getCode());
            }

            dtos.add(dto);
        }

        return dtos;
    }

    public void addInspectionCheck(AddInspectionCheckCommand command) {
        // 根据 inspectionId 获取检查计划信息
        SirInspectionDTO inspectionDTO = sirInspectionApplicationService.getInspectionInfo(command.getInspectionId());
        if (inspectionDTO != null) {
            // 将 SirInspectionDTO 的 deptId 和 inspectionDeptId 分别赋值给 AddInspectionCheckCommand 的 dutyDeptId 和 curDealDeptId
            command.setDutyDeptId(inspectionDTO.getDeptId());
            command.setCurDealDeptId(inspectionDTO.getInspectionDeptId());
        }

        InspectionCheckModel model = modelFactory.create();
        model.loadFromAddCommand(command);
        model.checkValid();
        model.insert();
    }

    public void updateInspectionCheck(UpdateInspectionCheckCommand command) {
        InspectionCheckModel model = modelFactory.loadById(command.getInspectionCheckId());
        model.loadFromUpdateCommand(command);
        model.checkValid();
        model.updateById();
    }

    public void deleteInspectionCheck(BulkOperationCommand<Long> command) {
        inspectionCheckService.removeBatchByIds(command.getIds());
    }

    // 新增开始检查接口
    public void startInspection(UpdateInspectionCheckCommand command) {
        // 根据 inspectionId 查找关联的 inspection 数据
        SirInspectionEntity inspection = sirInspectionService.getById(command.getInspectionId());
        if (inspection == null) {
            throw new RuntimeException("未找到对应的检查计划数据");
        }

        if (!inspection.getStatus().equals("4")) {
            // 第一次开启这个检查计划，设置计划的状态和开始时间
            UpdateSirInspectionCommand updateSirInspectionCommand = new UpdateSirInspectionCommand();
            updateSirInspectionCommand.setInspectionId(command.getInspectionId());
            updateSirInspectionCommand.setStartTime(new Date());
            updateSirInspectionCommand.setStatus("4");
            sirInspectionApplicationService.updateInspection(updateSirInspectionCommand);
        }


        // 删除原有的关联的整改以及安全信息
        sirReformMainService.deleteByInspectionCheckId(command.getInspectionCheckId());
        sirReportService.deleteByInspectionCheckId(command.getInspectionCheckId());






        // 根据 inspectionCheckid 查找 inspectionCheck 数据
        SirInspectionCheckEntity inspectionCheck = inspectionCheckService.getById(command.getInspectionCheckId());
        if (inspectionCheck == null) {
            throw new RuntimeException("未找到对应的检查项数据");
        }

        // 根据 selfcheckId 查找 SirSelfCheckEntity 数据
        SirSelfCheckDTO selfCheck = sirSelfCheckService.getInfo(inspectionCheck.getSelfcheckId());

        // 根据 inspectionUserId 查找用户数据
        UserDetailDTO userDetail = userApplicationService.getUserDetailInfo(command.getInspectionUserId());

        // 更新 inspectionCheckId 对应的数据：start_time 为当前时间
        inspectionCheck.setStartTime(new Date());
        inspectionCheck.setInspectionUserId(command.getInspectionUserId());
        if (command.getTittle()!=null){
            inspectionCheck.setTittle(command.getTittle());
        }

        //如果检查通过
        if ("1".equals(command.getInspectionResult())) {
            inspectionCheck.setInspectionResult("1");
            inspectionCheck.setInspectionUserId(command.getInspectionUserId());
            inspectionCheck.setDealType("0");
        } else if ("2".equals(command.getInspectionResult())) {
            inspectionCheck.setInspectionResult(command.getInspectionResult());
            inspectionCheck.setInspectionUserId(command.getInspectionUserId());
            inspectionCheck.setInspectionQuestion(command.getInspectionQuestion());
            inspectionCheck.setDealType(command.getDealType());
            inspectionCheck.setDutyDeptId(command.getDutyDeptId());
            inspectionCheck.setCurDealDeptId(command.getCurDealDeptId());

            if ("1".equals(command.getDealType())) {
                //            如果需要添加安全信息
                // 调用 ReformMainApplicationService.addReform 额外新增一条数据
                AddReformMainCommand reformCommand = new AddReformMainCommand();
                reformCommand.setInspectionCheckId(command.getInspectionCheckId());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                String codePrefix = inspection.getInspectionCode().substring(0, 4);
                reformCommand.setCode(codePrefix + sdf.format(new Date()));
                reformCommand.setRelatedQuestionId(command.getInspectionCheckId());
                reformCommand.setQuestionSourceName(mapCodeToNumber(codePrefix));
                reformCommand.setCheckDate(new Date());
                reformCommand.setInspectors(command.getInspector());
                reformCommand.setReformStatus("5");
                reformCommand.setQuestionTitle(command.getTittle());
                reformCommand.setReformTitle(new String(command.getInspectionQuestion(), StandardCharsets.UTF_8));
                reformCommand.setIssueDeptId(inspection.getInspectionDeptId());
                reformCommand.setDutyDeptId(command.getDutyDeptId());
                reformCommand.setCurDealDeptId(command.getCurDealDeptId());
                reformCommand.setCreateTime(new Date());
                reformCommand.setDeleted(false);
                reformCommand.setReformRequirement(command.getReformRequirement());
                reformCommand.setRequestFeedbackDate(command.getCorrectiveDeadline());
                reformCommand.setCorrectiveDeadline(command.getActionDeadline());
                reformCommand.setIsShareReport("F");
                reformMainApplicationService.addReform(reformCommand);
            } else if ("2".equals(command.getDealType())) {
                // 调用 ReportApplicationService 的 addReport 新增加一条数据
                AddReportCommand reportCommand = new AddReportCommand();
                reportCommand.setInspectionCheckId(command.getInspectionCheckId());
                reportCommand.setInfoSource(mapCodeToNumber(inspection.getInspectionCode().substring(0, 4)));
                reportCommand.setDutyDeptId(command.getDutyDeptId());
                reportCommand.setAcceptDeptId(command.getCurDealDeptId());
                reportCommand.setBasis(selfCheck.getComplianceCriteria());

                reportCommand.setTitle(command.getSafetyContent());
                reportCommand.setInfoDescribe(command.getInspectionQuestion());

                reportCommand.setContactPerson(command.getInspectionUserId());
                reportCommand.setDiscoveryPlace(command.getDiscoveryPlace());
                reportCommand.setDiscoveryDate(new Date());
                reportCommand.setDiscoverer(command.getInspectionUserId());
                reportCommand.setCreateTime(new Date());
                reportApplicationService.addReport(reportCommand);
            }
        } else if ("3".equals(command.getInspectionResult())) {
            // 当 inspectionResult 为 3 时，更新对应字段
            inspectionCheck.setInspectionResult(command.getInspectionResult());
            inspectionCheck.setInspectionUserId(command.getInspectionUserId());
            inspectionCheck.setInspectionQuestion(command.getInspectionQuestion());
        }

        // 保存更新后的检查项数据
        inspectionCheckService.updateById(inspectionCheck);
    }


    // 辅助方法：将检查代码前缀映射为数字
    private String mapCodeToNumber(String codePrefix) {
        Map<String, String> codeMap = new HashMap<>();
        codeMap.put("FDZC", "1");
        codeMap.put("ZXJC", "2");
        codeMap.put("AQZL", "3");
        return codeMap.getOrDefault(codePrefix, "未知类型");

    }
}